// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin_JXGM ql1746365080@gmail.com
 * @Date: 2024-10-16 09:35:57
 * @LastEditors: qiulin_JXGM ql1746365080@gmail.com
 * @LastEditTime: 2024-12-20 13:33:49
 * @FilePath: \SGFEM\Import\BDFImport\BulkData\Load\RLOAD1Parser.cpp
 */

#include "Import/BDFImport/BulkData/Load/RLOAD1Parser.h"

#include <algorithm>
#include <cstdint>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Load/IRLOAD1Service.h"

#include "Import/BDFImport/BDFParserBase.h"
BULKDATA_ENTRY_PARSER_REG (RLOAD1);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;
/*
// file://./../../Doc/MarkDown/BulkData/RLOAD1/RLOAD1.md>
*/
// 以下需要修改
enum RLOAD1key : std::uint8_t
{
    RLOAD1KEY_SID      = 2,
    RLOAD1KEY_EXCITEID = 3,  // 静态或热负载集合的识别号
    RLOAD1KEY_DELAY    = 4,  // DELAY或FBADLAY识别号  或者时间延迟τ
    RLOAD1KEY_DPHASEI  = 5,  // DPHASE或FBAPHAS识别号 或相位角θ
    RLOAD1KEY_TRC      = 6,  // 给出C(f)的TABLEDi条目的集合识别号或用于所有频率的C的值
    RLOAD1KEY_TRD      = 7,  // 给出D(f)的TABLEDi条目的集合识别号或用于所有频率的D的值
    RLOAD1KEY_TYPE     = 8,  // 定义动态激励的类型
};

namespace
{
    SG::DataStructure::Common::I64 getRload1Type (char& typeStr)
    {
        switch (typeStr)
        {
        case '0':
            return 0;
        case '1':
            return 1;
        case '2':
            return 2;
        case '3':
            return 3;
        case 'L':
            return 0;
        case 'D':
            return 1;
        case 'V':
            return 2;
        case 'A':
            return 3;
            break;
        default:
            throw std::runtime_error ("getRload1Type have a bad input:");
            throw std::runtime_error (typeStr + "\n");
            break;
        }
    }

}  // namespace

SG::DataStructure::Common::Status BDF::BULKDATA::ParseRLOAD1 (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                                              std::vector<std::string>&                               dividedEntryInfo)
{
    // 创建一个用于保存RLOAD1数据的临时结构体对象
    SG::DataStructure::FEM::RLOAD1Data tempRLOAD1;

    // TODO(bug 001) 填写m_domainId的正确值
    // 目前m_domainId硬编码为1，需要进一步确认是否正确
    tempRLOAD1.m_domainId = 1;

    // 将输入的条目信息分割成单个词条

    // 初始化当前处理的字符串条目的ID
    int curIDKey = 1;

    // 遍历所有分割后的条目信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 判断当前条目是否为空（即是否全为空格）
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            // 如果当前条目为空，跳过当前循环并处理下一个条目
            curIDKey++;
            continue;
        }

        // 将当前条目转换为科学计数法表示的数值
        bool isfloat = covertToScientificNotation (curStrKey);

        // 根据条目ID，将解析后的数值存入对应的RLOAD1字段
        switch (curIDKey)
        {
        case RLOAD1KEY_SID:
            tempRLOAD1.m_sId = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_EXCITEID:
            tempRLOAD1.m_DAREA = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_DELAY:
            isfloat ? tempRLOAD1.m_T = convertToReal (curStrKey) : tempRLOAD1.m_DELAY = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_DPHASEI:
            isfloat ? tempRLOAD1.m_PH = convertToReal (curStrKey) : tempRLOAD1.m_DPHASE = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_TRC:
            isfloat ? tempRLOAD1.m_RC = convertToReal (curStrKey) : tempRLOAD1.m_TC = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_TRD:
            isfloat ? tempRLOAD1.m_RD = convertToReal (curStrKey) : tempRLOAD1.m_TD = convertToI64 (curStrKey);
            break;
        case RLOAD1KEY_TYPE:
            // 解析第二个gi值并赋值
            tempRLOAD1.m_TYPE = getRload1Type (curStrKey[0]);
            break;
        default:
            // 如果条目ID不匹配，跳过处理
            break;
        }

        // 增加条目ID，以便处理下一个条目
        curIDKey++;
    }

    // 将解析后的RLOAD1数据通过数据库服务工厂的RLOAD1服务添加到数据库中
    return dbServiceFactory->get<IRLOAD1Service> ()->Add (tempRLOAD1);
}